import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

/**
 * Three.js 模型截图函数
 * @param {THREE.Scene} scene - 当前3D场景（包含你的保护壳模型）
 * @param {THREE.Camera} camera - 当前相机（确保角度和你看到的视图一致）
 * @param {Object} options - 截图配置
 * @param {number} [options.width=500] - 截图宽度（默认500px，适合缩略图）
 * @param {number} [options.height=500] - 截图高度（默认500px）
 * @param {boolean} [options.transparent=true] - 是否透明背景（保护壳模型推荐true）
 * @param {string} [options.format='image/png'] - 图片格式（png支持透明，jpg不支持）
 * @param {number} [options.quality=0.9] - 图片质量（0~1，仅jpg有效）
 * @returns {Promise<string|Blob>} - 截图结果（默认返回base64，可配置返回Blob）
 */
export function captureModelScreenshot(
    scene: THREE.Scene,
    camera: THREE.Camera,
    options: {
        width?: number;
        height?: number;
        transparent?: boolean;
        format?: string;
        quality?: number;
        returnBlob?: boolean;
    } = {}
    ): Promise<string | Blob> {
    return new Promise((resolve, reject) => {
        // 1. 配置默认参数
        const {
        width = 500,
        height = 500,
        transparent = true,
        format = 'image/png',
        quality = 0.9,
        returnBlob = false,
        } = options;

        // 2. 创建离屏Canvas（不影响主渲染）
        const offscreenCanvas = document.createElement('canvas');
        offscreenCanvas.width = width;
        offscreenCanvas.height = height;

        // 3. 初始化临时Renderer（参数和主Renderer对齐，确保渲染效果一致）
        const tempRenderer = new THREE.WebGLRenderer({
        canvas: offscreenCanvas,
        antialias: true, // 抗锯齿，避免截图模糊
        alpha: transparent, // 支持透明背景
        preserveDrawingBuffer: true, // 必须开启，否则无法提取图片
        });
        // 匹配主渲染的像素比（解决高清屏模糊问题）
        tempRenderer.setPixelRatio(window.devicePixelRatio || 1);
        tempRenderer.setSize(width, height);

        try {
        // 4. 渲染场景到离屏Canvas
        // 清除背景（透明背景时设为rgba(0,0,0,0)）
        tempRenderer.setClearColor(0x000000, transparent ? 0 : 1);
        tempRenderer.clear();
        // 渲染当前模型和相机视角
        tempRenderer.render(scene, camera);

        // 5. 提取图片数据
        if (returnBlob) {
            // 返回Blob（适合上传服务器）
            offscreenCanvas.toBlob(
            (blob) => {
                if (blob) resolve(blob);
                else reject(new Error('生成Blob失败'));
            },
            format,
            quality
            );
        } else {
            // 返回base64（适合直接展示在img标签）
            const base64 = offscreenCanvas.toDataURL(format, quality);
            resolve(base64);
        }
        } catch (error) {
        reject(new Error(`截图失败：${(error as Error).message}`));
        } finally {
        // 6. 清理临时资源（避免内存泄漏）
        tempRenderer.dispose();
        // 移除离屏Canvas（可选，不影响但推荐清理）
        offscreenCanvas.remove();
        }
    });
}

// 定义“固定视角”的配置（你需要根据实际好看的角度调整这些值）
const FIXED_VIEW_CONFIG = {
    // 相机位置（绝对坐标）
    cameraPosition: new THREE.Vector3(6.817373254070606, -1.9466769649446927, -10.72984371272301), // 示例值，需自己调整
    // 相机看向的目标点（场景中心）
    cameraTarget: new THREE.Vector3(6.287276679909506, -1.795309751846986, -9.895526273817591),
    // 场景旋转角度（弧度，固定为0表示场景不旋转，仅通过相机控制视角）
    sceneRotation: new THREE.Euler(0, 0, 0) // 关键：场景不旋转，避免叠加混乱
};

/**
 * 强制将场景和相机重置到固定视角（无视之前的任何操作）
 * @param scene 场景实例
 * @param camera 相机实例
 * @param controls 控制器实例
 */
export function resetToFixedView(
    scene: THREE.Scene,
    camera: THREE.Camera,
    controls: OrbitControls
) {
    // 参数校验
    if (!(scene instanceof THREE.Scene) || !(camera instanceof THREE.Camera) || !(controls instanceof OrbitControls)) {
    console.error('参数错误：必须传入有效的scene、camera、controls实例');
    return;
    }

    // 1. 强制重置场景旋转（固定为0，避免旋转叠加）
    scene.rotation.copy(FIXED_VIEW_CONFIG.sceneRotation);

    // 2. 强制设置相机位置（绝对坐标，不依赖当前位置）
    camera.position.copy(FIXED_VIEW_CONFIG.cameraPosition);

    // 3. 强制设置相机目标点（始终看向场景中心）
    camera.lookAt(FIXED_VIEW_CONFIG.cameraTarget);

    // 4. 重置控制器状态（清除所有拖动产生的旋转记录）
    controls.reset();
    controls.target.copy(FIXED_VIEW_CONFIG.cameraTarget);
    controls.update();

    // 5. 立即渲染，确保画面同步
    const renderer = scene.parent?.parent as THREE.WebGLRenderer; // 假设renderer可访问
    if (renderer) renderer.render(scene, camera);

    console.log('已强制重置到固定视角');
}

// 将模型缩放到指定大小
export function scaleModel(model: THREE.Object3D, size: number) {
    const boundingBox = new THREE.Box3().setFromObject(model);
    const maxDimension = Math.max(boundingBox.max.x - boundingBox.min.x, boundingBox.max.y - boundingBox.min.y, boundingBox.max.z - boundingBox.min.z);
    const scale = size / maxDimension; // 计算缩放比例
    model.scale.set(scale, scale, scale); // 应用缩放
    return model;
}

/**
 * 调试用：获取当前视角配置（用于确定FIXED_VIEW_CONFIG的值）
 * @param scene 场景实例
 * @param camera 相机实例
 */
export function getCurrentViewConfig(
    scene: THREE.Scene,
    camera: THREE.Camera
) {
    return {
    cameraPosition: camera.position.clone(),
    cameraTarget: new THREE.Vector3().copy(camera.getWorldDirection(new THREE.Vector3())).add(camera.position),
    sceneRotation: scene.rotation.clone()
    };
}

/**
 * 精简版模型自动旋转控制器
 * 核心功能：自动旋转、鼠标操作暂停、无操作恢复、完全暂停（截图用）
 * @param {THREE.Object3D} model - 模型对象
 * @param {THREE.OrbitControls} controls - 轨道控制器
 * @param {number} speed - 旋转速度（默认0.005）
 * @param {number} idleTime - 无操作恢复时间(毫秒，默认3000)
 */
export function setupAutoRotate(model, controls, speed = 0.005, idleTime = 3000) {
    let isRotating = true; // 是否正在自动旋转
    let idleTimer = null;  // 闲置计时器
    const resetIdle = resetIdleTimer; // 保存事件回调引用

    // 初始化控制器
    controls.autoRotate = false;
    controls.enableDamping = true;
    controls.dampingFactor = 0.05;

    // 闲置时恢复旋转
    function resetIdleTimer() {
        if (isRotating) isRotating = false; // 操作时停止旋转
        clearTimeout(idleTimer);
        idleTimer = setTimeout(() => { isRotating = true; }, idleTime);
    }

    // 监听鼠标操作事件
    controls.addEventListener('start', resetIdle);
    controls.addEventListener('change', resetIdle);

    // 动画更新（必须在动画循环中调用）
    function update() {
        controls.update();
        if (isRotating) model.rotation.y += speed;
    }

    // 核心API（只保留最常用的）
    return {
        /** 启动自动旋转 */
        start: () => {
            isRotating = true;
            clearTimeout(idleTimer);
        },

        /** 停止自动旋转（但保留事件监听，可能被鼠标操作重新触发） */
        stop: () => {
            isRotating = false;
            clearTimeout(idleTimer);
        },

        /** 完全暂停（用于截图）：停止旋转+禁用事件监听，彻底不自动恢复 */
        pauseForScreenshot: () => {
            isRotating = false;
            clearTimeout(idleTimer);
            controls.removeEventListener('start', resetIdle);
            controls.removeEventListener('change', resetIdle);
        },

        /** 截图后恢复：重新启用事件监听+可选重启旋转 */
        resumeAfterScreenshot: (restart = true) => {
            controls.addEventListener('start', resetIdle);
            controls.addEventListener('change', resetIdle);
            if (restart) isRotating = true;
        },

        /** 动画更新函数（必须在requestAnimationFrame中调用） */
        update,

        /** 销毁控制器（清理事件） */
        dispose: () => {
            controls.removeEventListener('start', resetIdle);
            controls.removeEventListener('change', resetIdle);
            clearTimeout(idleTimer);
        }
    };
}

// 使用示例（截图流程）
/*
// 初始化自动旋转
const autoRotate = setupAutoRotate(model, controls, 0.005, 3000);

// 截图按钮点击事件
document.getElementById('screenshotBtn').addEventListener('click', async () => {
    // 1. 完全暂停（停止旋转+禁用事件，确保不会自动恢复）
    autoRotate.pauseForScreenshot();

    // 2. 调整到截图视角（缩放+角度）
    await setupScreenshotWithZoom(zoom, controls, camera, {
        zoomDistance: 15,
        theta: Math.PI / 6,
        phi: Math.PI / 4,
        targetX: 0,
        targetY: 1,
        targetZ: 0
    });

    // 3. 截图
    captureScreenshot(renderer);

    // 4. 恢复（重新启用事件+重启自动旋转）
    autoRotate.resumeAfterScreenshot(true);
    controls.enabled = true;
});

// 动画循环
function animate() {
    requestAnimationFrame(animate);
    autoRotate.update(); // 必须调用
    renderer.render(scene, camera);
}
animate();
*/

/**
 * 调整轨道控制器的当前缩放比例（相机与模型的距离）
 * 不改变模型本身大小，只改变视图远近
 * @param {THREE.OrbitControls} controls - 轨道控制器实例
 * @param {THREE.Camera} camera - 相机实例
 */
export const ZoomController = (controls, camera) => {
    // 获取当前相机到目标点的距离
    const getCurrentDistance = () => {
        return camera.position.distanceTo(controls.target);
    };

    // 放大视图（减小相机与目标的距离）
    const zoomIn = (factor = 0.1) => {
        // 计算新距离（当前距离 * (1 - 缩放因子)）
        const currentDistance = getCurrentDistance();
        const newDistance = currentDistance * (1 - factor);
        
        // 确保不小于最小允许距离
        const clampedDistance = Math.max(newDistance, controls.minDistance);
        
        // 调整相机位置（保持方向不变，只改变距离）
        camera.position.subVectors(camera.position, controls.target)
                  .setLength(clampedDistance)
                  .add(controls.target);
        
        // 更新控制器状态
        controls.update();
    };

    // 缩小视图（增大相机与目标的距离）
    const zoomOut = (factor = 0.1) => {
        // 计算新距离（当前距离 * (1 + 缩放因子)）
        const currentDistance = getCurrentDistance();
        const newDistance = currentDistance * (1 + factor);
        
        // 确保不大于最大允许距离
        const clampedDistance = Math.min(newDistance, controls.maxDistance);
        
        // 调整相机位置
        camera.position.subVectors(camera.position, controls.target)
                  .setLength(clampedDistance)
                  .add(controls.target);
        
        // 更新控制器状态
        controls.update();
    };

    // 直接设置到指定距离（最常用的功能）
    const setZoomDistance = (distance) => {
        // 限制在允许的范围内
        const clampedDistance = Math.max(
            controls.minDistance,
            Math.min(distance, controls.maxDistance)
        );
        
        // 调整相机位置到指定距离
        camera.position.subVectors(camera.position, controls.target)
                  .setLength(clampedDistance)
                  .add(controls.target);
        
        // 更新控制器
        controls.update();
    };

    // 重置到初始缩放（需要记录初始距离）
    const resetZoom = (initialDistance) => {
        setZoomDistance(initialDistance);
    };

    return {
        getCurrentDistance,
        zoomIn,       // 放大（参数为缩放幅度，0.1表示放大10%）
        zoomOut,      // 缩小（参数为缩放幅度，0.1表示缩小10%）
        setZoomDistance,  // 直接设置距离（如setZoomDistance(5)）
        resetZoom     // 重置到初始缩放
    };
};

// 使用示例
/*
// 在你的Three.js场景中
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

// 初始化场景、相机、渲染器
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 添加模型（示例）
const model = new THREE.Mesh(
    new THREE.BoxGeometry(2, 2, 2),
    new THREE.MeshBasicMaterial({ color: 0x00ff00 })
);
scene.add(model);

// 初始化相机位置（记录初始距离用于重置）
const initialCameraDistance = 10; // 初始距离模型10个单位
camera.position.z = initialCameraDistance;

// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
// 配置缩放范围（确保setZoomDistance不会超出这个范围）
controls.minDistance = 3;   // 最近能放大到距离3
controls.maxDistance = 20;  // 最远能缩小到距离20

// 初始化缩放控制器
const zoom = ZoomController(controls, camera);

// 示例：绑定按钮事件（实际项目中根据需要调用）
document.getElementById('zoomInBtn').addEventListener('click', () => {
    zoom.zoomIn(0.2); // 放大20%
});

document.getElementById('zoomOutBtn').addEventListener('click', () => {
    zoom.zoomOut(0.2); // 缩小20%
});

document.getElementById('resetZoomBtn').addEventListener('click', () => {
    zoom.resetZoom(initialCameraDistance); // 重置到初始缩放
});

document.getElementById('setZoom5Btn').addEventListener('click', () => {
    zoom.setZoomDistance(5); // 直接设置到距离5
});

// 动画循环
function animate() {
    requestAnimationFrame(animate);
    controls.update();
    renderer.render(scene, camera);
}
animate();
*/

/**
 * 结合ZoomController控制缩放，再调整固定角度，为截图做准备
 * @param {Object} zoom - 之前创建的ZoomController实例
 * @param {THREE.OrbitControls} controls - 轨道控制器实例
 * @param {THREE.Camera} camera - 相机实例
 * @param {Object} config - 配置参数
 * @param {number} config.zoomDistance - 目标缩放距离（通过ZoomController控制）
 * @param {number} config.theta - 水平旋转角度（弧度，0-2π）
 * @param {number} config.phi - 垂直旋转角度（弧度，0-π）
 * @param {number} [config.targetX=0] - 模型中心点X
 * @param {number} [config.targetY=0] - 模型中心点Y
 * @param {number} [config.targetZ=0] - 模型中心点Z
 * @returns {Promise} - 准备完成后resolve，可执行截图
 */
export function setupScreenshotWithZoom(zoom, controls, camera, config) {
    return new Promise((resolve) => {

        // 1. 先通过ZoomController设置缩放（复用之前的缩放控制逻辑）
        // zoom.setZoomDistance(config.zoomDistance);

        // 2. 设置模型中心点（目标点）
        controls.target.set(
            config.targetX || 0,
            config.targetY || 0,
            config.targetZ || 0
        );

        // 3. 计算固定角度的相机位置（仅调整角度，不改变已设置的缩放距离）
        const currentDistance = zoom.getCurrentDistance(); // 获取ZoomController设置的距离
        const theta = config.theta; // 水平角度（必须指定）
        const phi = config.phi;     // 垂直角度（必须指定）

        // 球面坐标转笛卡尔坐标（保持当前缩放距离，只改变角度）
        const x = currentDistance * Math.sin(phi) * Math.cos(theta);
        const y = currentDistance * Math.cos(phi);
        const z = currentDistance * Math.sin(phi) * Math.sin(theta);

        // 4. 应用角度（保持缩放距离不变）
        camera.position.set(
            x + controls.target.x,
            y + controls.target.y,
            z + controls.target.z
        );
        camera.lookAt(controls.target);

        if (config.unStop) return

        // 5. 临时禁用交互，防止截图前误操作
        controls.enabled = false;

        // 6. 强制更新并等待一段时间稳定
        controls.update();
        setTimeout(() => {
            resolve();
        }, 500);
    });
}

export const link = (type: string = 'index', lang: string = 'en') => {
    let url = ''
    if (type == 'index') {
        if (lang == 'en') url = 'https://ficrcu-qn.myshopify.com/'
        else url = 'https://koduckya.shop/'
    }
    else if (type == 'shop') {
        if (lang == 'en') url = 'https://ficrcu-qn.myshopify.com/collections/all'
        else url = 'https://koduckya.shop/collections/all'
    }
    else if (type == 'contact') {
        if (lang == 'en') url = 'https://ficrcu-qn.myshopify.com/pages/contact'
        else url = 'https://koduckya.shop/pages/contact'
    }
    else if (type == 'order') url = 'https://shopify.com/72663073017/account/orders'
    else if (type == 'custom') {
        // 刷新
        window.location.reload()
    }
    // 同一个页面跳转
    window.location.href = url
}

// 指定可滚动元素滚动到指定高度
export const scrollTo = (height: number = 0, dom: HTMLElement = document.documentElement) => {
    dom.scrollTo({
        top: height,
        behavior: 'smooth'
    })
}